<template>
  <div class="app-container">
    <!-- 条件查询区域开始 -->
    <div class="search-container">
      <el-form ref="queryFormRef" :model="queryParams" :inline="true">
        <el-form-item :label="$t('procInst.procDefName')" prop="procDefKey">
          <jmash-select
            :placeholder="$t('procInst.procDefNamePlaceholder')"
            :data="Dict.procDict.values"
            v-model="queryParams.procDefKey"
          ></jmash-select>
        </el-form-item>
        <!-- 事项分类 -->
        <el-form-item :label="$t('task.category')" prop="category">
          <el-tree-select
            v-model="queryParams.category"
            :data="Dict.categoryCodeDict.values"
            filterable
            clearable
            check-strictly
            class="w-full"
            :render-after-expand="false"
            :placeholder="$t('task.categoryPlaceholder')"
          />
        </el-form-item>
        <el-form-item :label="$t('task.priority')" prop="priority">
          <jmash-select
            :placeholder="$t('task.priorityPlaceholder')"
            :data="Dict.priorityDict.values"
            v-model="queryParams.priority"
          ></jmash-select>
        </el-form-item>
        <el-form-item class="search-btn">
          <el-button type="primary" @click="tableHooks.handleQuery()">
            {{ $t("common.search") }}
          </el-button>
          <el-button @click="tableHooks.resetQuery()">{{
            $t("common.reset")
          }}</el-button>
        </el-form-item>
      </el-form>
    </div>
    <el-tabs type="border-card" v-model="activeName" @tab-click="tabClick">
      <el-tab-pane label="我的任务" name="assignee"></el-tab-pane>
      <el-tab-pane label="候选任务" name="candidate"></el-tab-pane>

      <!-- 条件查询区域结束 -->
      <el-card shadow="never" class="table-container">
        <!-- 按钮开始 -->
        <template #header>
          <!-- 按钮开始 -->
          <el-row justify="space-between" :span="8">
            <el-col :span="12">
              <el-button
                type="primary"
                v-hasRole="['admin']"
                @click="handleAdd"
              >
                {{ $t("common.add") }}
              </el-button></el-col
            >
            <el-col :span="8" align="right">
              <jmash-column-select
                v-model="tableLabel"
                label-name="flow/monitor"
              />
            </el-col>
          </el-row>
        </template>
        <!-- 按钮结束 -->
        <!-- 表格开始 -->
        <jmash-table
          class="table-top"
          ref="multipleTableRef"
          row-key="id"
          :list-loading="listLoading"
          :data="tableData"
          :table-label="tableLabel"
          @selection-change="tableSelected"
          @sort-change="handleSort"
        >
          <template #startUserId="scope">
            <span>{{
              rbacApi.userInfo(
                scope.data.row.startUserId,
                vueMetaEnv.APP_TENANT,
              ).realName
            }}</span>
          </template>
          <template #createTime="scope">
            <span>{{
              format(new Date(scope.data.row.createTime), "yyyy-MM-dd HH:mm:ss")
            }}</span>
          </template>
          <template #assignee="scope">
            <span>{{
              rbacApi.userInfo(scope.data.row.assignee).nickName
            }}</span>
          </template>
          <!-- 优先级 -->
          <template #priority="scope">
            {{ Dict.priorityDict.getValue(scope.data.row.priority) }}
          </template>
          <template #category="scope">
            {{ Dict.categoryCodeDict.getValue(scope.data.row.category) }}
          </template>
          <!-- 描述 -->
          <template #description="scope">
            <span>{{ queryProVas(scope.data.row) }}</span>
          </template>
          <template #operation="scope">
            <span
              class="el-button-color"
              @click="handleViewDiagram(scope.data.row)"
            >
              {{ $t("flow.viewDiagram") }}
            </span>
            <!--处理-->
            <span
              class="el-button-color dropdown-left"
              v-if="!queryParams.candidate"
              @click="handleTask(scope.data.row)"
            >
              {{ $t("flow.handle") }}
            </span>
            <el-dropdown
              class="dropdown-left"
              v-if="shouldShowMenu(scope.data.row)"
            >
              <span class="el-dropdown-link">
                {{ $t("common.more") }}
                <el-icon class="el-icon--right">
                  <arrow-down />
                </el-icon>
              </span>
              <template #dropdown>
                <el-dropdown-menu>
                  <!-- 模版消息 -->
                  <div v-hasPerm="['wechat:user:update']">
                    <el-dropdown-item @click="handleMessage(scope.data.row)">
                      {{ $t("flow.message") }}
                    </el-dropdown-item>
                  </div>
                  <!-- 认领 -->
                  <div
                    v-if="
                      queryParams.candidate && scope.data.row.assignee === ''
                    "
                  >
                    <el-dropdown-item @click="claimTask(scope.data.row, true)">
                      {{ $t("flow.claim") }}
                    </el-dropdown-item>
                  </div>
                  <!--取回认领-->
                  <div
                    v-if="
                      queryParams.candidate && scope.data.row.assignee !== ''
                    "
                  >
                    <el-dropdown-item
                      @click="claimTask(scope.data.row, false, true)"
                    >
                      {{ $t("flow.forceunclaim") }}
                    </el-dropdown-item>
                  </div>
                  <!--取消认领-->
                  <div
                    v-if="
                      !queryParams.candidate && scope.data.row.claimedBy !== ''
                    "
                  >
                    <el-dropdown-item @click="claimTask(scope.data.row, false)">
                      {{ $t("flow.unclaim") }}
                    </el-dropdown-item>
                  </div>
                </el-dropdown-menu>
              </template>
            </el-dropdown>
          </template>
        </jmash-table>
        <template #footer>
          <jmash-pagination
            v-if="total > 0"
            v-model:total="total"
            v-model:current-page="queryParams.curPage"
            v-model:page-size="queryParams.pageSize"
            @pagination="tableHooks.getList()"
          />
        </template>
      </el-card>
    </el-tabs>
    <holiday-request-create
      v-if="createDialog.visible"
      v-model="createDialog.visible"
      :title="createDialog.title"
    ></holiday-request-create>
    <procinit-diagram
      v-if="viewDialog.visible"
      v-model="viewDialog.visible"
      :title="viewDialog.title"
      :entity-key="procInstKey"
      width="900px"
    />
  </div>
</template>
<script setup lang="ts">
import { type Ref, ref, reactive, onActivated, computed } from "vue";
import {
  type TableColumn,
  type DialogRef,
  type TableSort,
  useTableHooks,
  vueMetaEnv,
  useUserStoreHook,
} from "jmash-core";
import { Dict } from "@/api/flow/dict";
import { format } from "date-fns";
import { type TabsPaneContext } from "element-plus";
import { rbacApi } from "jmash-rbac";
import { useRouter } from "vue-router";
import { useI18n } from "vue-i18n";
const { t } = useI18n();
import type {
  FlowTaskModel,
  TaskReq,
  FlowProcInstKey,
  FlowClaimTaskRequest,
} from "@/api/flow/task/types";

import { taskApi } from "@/api/flow/task/index";
import procinitDiagram from "@/views/flow/common/procinst-diagram-dialog.vue";

const activeName = ref("assignee");

const queryParams = ref<TaskReq>({});
// 分类层级字典
Dict.categoryCodeDict.useValues();
// 流程
Dict.procDict.useValues();
//切换Tab
const tabClick = (tab: TabsPaneContext, event: Event) => {
  queryParams.value.candidate = tab.props.name === "candidate";
  tableHooks.getList();
};

const {
  tableHooks,
  multipleTableRef,
  queryFormRef,
  listLoading,
  tableData,
  total,
} = useTableHooks(t, taskApi, queryParams);

const shouldShowMenu = computed(() => (row: FlowTaskModel) => {
  const userStore = useUserStoreHook();
  const hasMessagePermission =
    userStore.user.permCodes.includes("wechat:user:update");
  // 2. 检查是否显示 "认领" 选项
  console.log("shouldShowMenu", hasMessagePermission);
  const showClaim = queryParams.value.candidate && row.assignee === "";

  // 3. 检查是否显示 "取回认领" 选项
  const showForceUnclaim = queryParams.value.candidate && row.assignee !== "";

  // 4. 检查是否显示 "取消认领" 选项
  const showUnclaim = !queryParams.value.candidate && row.claimedBy !== "";

  // 如果任何一个条件满足，就显示菜单，否则隐藏
  return hasMessagePermission || showClaim || showForceUnclaim || showUnclaim;
});

let tableLabel: Ref<TableColumn[]> = ref([
  {
    label: "task.procInstName",
    prop: "procInstName",
    minWidth: "150",
    isColumn: true,
  },
  {
    label: "task.category",
    prop: "category",
    slotName: "category",
    columnType: "slot",
    width: "150",
    isColumn: true,
  },
  {
    label: "task.name",
    prop: "name",
    width: "150",
    isColumn: true,
  },
  {
    label: "task.startUserId",
    prop: "startUserId",
    width: "120",
    slotName: "startUserId",
    columnType: "slot",
    isColumn: true,
  },
  {
    label: "task.businessStatus",
    prop: "businessStatus",
    width: "120",
    isColumn: true,
  },
  {
    label: "task.createTime",
    prop: "createTime",
    slotName: "createTime",
    width: "160",
    columnType: "slot",
    sortable: "custom",
    isColumn: true,
  },
  {
    label: "task.dueDate",
    prop: "dueDate",
    width: "160",
    sortable: "custom",
    isColumn: false,
  },
  {
    label: "task.curUser",
    prop: "assignee",
    width: "120",
    slotName: "assignee",
    columnType: "slot",
    isColumn: true,
  },
  {
    label: "task.priority",
    prop: "priority",
    width: "80",
    slotName: "priority",
    columnType: "slot",
    isColumn: true,
    editable: true,
  },
  {
    label: "task.description",
    prop: "description",
    slotName: "description",
    columnType: "slot",
    isColumn: true,
    editable: true,
  },
  {
    label: "common.operate",
    width: "200",
    slotName: "operation",
    columnType: "slot",
    fixed: "right",
    isColumn: true,
  },
]);

// 查看Dialog
const viewDialog = ref({
  title: t("flow.viewDiagram"),
  visible: false,
} as DialogRef);

//查看Dialog
const createDialog = ref({
  title: "创建请假流程实例",
  visible: false,
} as DialogRef);
//流程实例Key.
let procInstKey = reactive<FlowProcInstKey>({});

// 查看流程图
function handleViewDiagram(row: FlowTaskModel) {
  procInstKey.procInstId = row.processInstanceId;
  viewDialog.value.visible = true;
}

const router = useRouter();
// 处理任务
function handleTask(row: FlowTaskModel) {
  router.push({
    path: "/rawflow/task/dealwith",
    query: { taskId: row.id },
  });
}

// 认领和取消认领
function claimTask(row: FlowTaskModel, claim: boolean, force: boolean = false) {
  let req: FlowClaimTaskRequest = {
    requestId: Math.random() * 10 + "",
    taskId: [],
  };
  req.taskId?.push(row.id as string);
  req.claim = claim;
  req.force = force;
  taskApi.claimTask(req).then((res) => {
    tableHooks.getList();
  });
}

// 行选择
function tableSelected(value: FlowTaskModel[]) {
  tableHooks.selectionRows.value = value;
}

//处理排序
function handleSort(sort: TableSort) {
  //Flowable 排序方式.
  let orderName = sort.prop;
  tableHooks.handleSort(orderName, sort.order);
}

let focus: boolean = false;
function focusPriority(row: FlowTaskModel) {
  focus = true;
}

//优先级变化
function changePriority(row: FlowTaskModel) {
  if (row.id && focus === true) {
    // const request = {
    //   requestId: Math.random() * 10 + "p",
    //   taskId: row.id,
    //   priority: row.priority,
    // } as FlowPriorityTaskRequest;
    // console.log(request);
    // taskApi.priorityTask(request).then((res) => {
    //   focus = false;
    // });
  }
}

function handleAdd() {
  createDialog.value.visible = true;
}

//查询数据.
onActivated(() => {
  tableHooks.getList();
});

/**
 * 查询流程变量并更新任务描述
 *
 * @param {FlowTaskModel} row - 流程任务模型对象，包含流程实例ID等信息
 * @returns {string|undefined} 返回任务描述信息，如果流程实例ID不存在则返回undefined
 */

// 缓存已请求的 processInstanceId 及其结果
const processInstanceCache = new Map<string, Promise<any>>();
function queryProVas(row: FlowTaskModel) {
  console.log("查询流程变量", row.processInstanceId);

  // 如果没有 processInstanceId，则直接返回
  if (!row.processInstanceId) return;

  let requestPromise: Promise<any>;

  // 检查是否已有缓存
  if (processInstanceCache.has(row.processInstanceId)) {
    // 使用缓存中的请求 Promise
    requestPromise = processInstanceCache.get(row.processInstanceId)!;
  } else {
    // 发起新请求并将其存入缓存
    requestPromise = taskApi.findProcinstId({
      procInstId: row.processInstanceId,
    });
    processInstanceCache.set(row.processInstanceId, requestPromise);
  }

  // 处理响应数据
  requestPromise.then(({ data }) => {
    row.description =
      data?.vars["description"] && data?.vars["description"].value;
  });

  return row.description;
}

// 发送模版消息
function handleMessage(row: FlowTaskModel) {
  let authorizerAppid = localStorage.getItem("authorizerAppid");
  router.push({
    path: "/rawflow/todotask/sendMessage",
    query: {
      userId: row.startUserId,
      authorizerAppid: authorizerAppid,
      procInstName: row.procInstName,
    },
  });
}
</script>
